﻿Imports WindowsApplication1.GoogleAnalyticsMailHandler
Imports System.Text.RegularExpressions
Imports System.Text

Public Class EmailViewerControl

    Protected Shared CharsetRegex As New Regex("charset=""?(?<charset>[^\s""]+)""?", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
    Protected Shared QuotedPrintableRegex As New Regex("=(?<hexchars>[0-9a-fA-F]{2,2})", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
    Protected Shared UrlRegex As New Regex("(?<url>https?://[^\s""]+)", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
    Protected Shared FilenameRegex As New Regex("filename=""?(?<filename>[^\s""]+)""?", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
    Protected Shared NameRegex As New Regex("name=""?(?<filename>[^\s""]+)""?", RegexOptions.IgnoreCase Or RegexOptions.Compiled)


    Public Sub SetEmail(ByVal email As GoogleAnalyticsMailHandler.Email)
        If Not email Is Nothing Then
            lblSubject.Text = email.Subject
            lblTo.Text = email.ToContact
            lblFrom.Text = email.FromContact

            SetEmailContents(email)
        End If
    End Sub




    Private Sub SetEmailContents(ByVal email As GoogleAnalyticsMailHandler.Email)
        Dim preferredMsgPart As MessagePart = FindMessagePart(email.MsgParts, "text/html")
        If preferredMsgPart Is Nothing Then
            preferredMsgPart = FindMessagePart(email.MsgParts, "text/plain")
        ElseIf preferredMsgPart Is Nothing AndAlso email.MsgParts.Count > 0 Then
            preferredMsgPart = email.MsgParts(0)
        End If
        Dim contentType As String, charset As String, contentTransferEncoding As String, body As String = Nothing
        If preferredMsgPart IsNot Nothing Then
            contentType = preferredMsgPart.Headers("Content-Type")
            charset = "us-ascii"
            contentTransferEncoding = preferredMsgPart.Headers("Content-Transfer-Encoding")
            Dim m As Match = CharsetRegex.Match(contentType)
            If m.Success Then
                charset = m.Groups("charset").Value
            End If

            If contentTransferEncoding IsNot Nothing Then
                If contentTransferEncoding.ToLower() = "base64" Then
                    body = DecodeBase64String(charset, preferredMsgPart.MessageText)
                ElseIf contentTransferEncoding.ToLower() = "quoted-printable" Then
                    body = DecodeQuotedPrintableString(preferredMsgPart.MessageText)
                Else
                    body = preferredMsgPart.MessageText
                End If
            Else
                body = preferredMsgPart.MessageText
            End If
        End If

        DisplayHtml(If(preferredMsgPart IsNot Nothing, (If(preferredMsgPart.Headers("Content-Type").IndexOf("text/plain") <> -1, "<pre>" + FormatUrls(body) + "</pre>", body)), Nothing))
        ' ListAttachments(msgParts)


    End Sub

    Private Sub DisplayHtml(ByVal html As String)

        webBrowser1.Navigate("about:blank")

        If webBrowser1.Document IsNot Nothing Then

            webBrowser1.Document.Write(String.Empty)

        End If

        webBrowser1.DocumentText = html

    End Sub


    Protected Function FindMessagePart(msgParts As List(Of MessagePart), contentType As String) As MessagePart
        For Each p As MessagePart In msgParts
            If p.ContentType IsNot Nothing AndAlso p.ContentType.IndexOf(contentType) <> -1 Then
                Return p
            End If
        Next
        Return Nothing
    End Function


    Protected Function DecodeBase64String(charset As String, encodedString As String) As String
        Dim decoder As Decoder = GetDecoder(charset)
        Dim buffer As Byte() = Convert.FromBase64String(encodedString)
        Dim chararr As Char() = New Char(decoder.GetCharCount(buffer, 0, buffer.Length) - 1) {}
        decoder.GetChars(buffer, 0, buffer.Length, chararr, 0)
        Return New String(chararr)
    End Function
    Protected Function DecodeQuotedPrintableString(encodedString As String) As String
        Dim b As New StringBuilder()
        Dim startIndx As Integer = 0
        Dim matches As MatchCollection = QuotedPrintableRegex.Matches(encodedString)
        For i As Integer = 0 To matches.Count - 1
            Dim m As Match = matches(i)
            Dim hexchars As String = m.Groups("hexchars").Value
            Dim charcode As Integer = Convert.ToInt32(hexchars, 16)
            Dim c As Char = CChar(ChrW(charcode))
            If m.Index > 0 Then
                b.Append(encodedString.Substring(startIndx, (m.Index - startIndx)))
            End If
            b.Append(c)
            startIndx = m.Index + 3
        Next
        If startIndx < encodedString.Length Then
            b.Append(encodedString.Substring(startIndx))
        End If
        Return Regex.Replace(b.ToString(), "=" & vbCr & vbLf, "")
    End Function
    'Protected Sub ListAttachments(msgParts As List(Of MessagePart))
    '    Dim attachmentsFound As Boolean = False
    '    Dim b As New StringBuilder()
    '    b.Append("<ol>")
    '    For Each p As MessagePart In msgParts
    '        Dim contentType As String = p.Headers("Content-Type")
    '        Dim contentDisposition As String = p.Headers("Content-Disposition")
    '        Dim m As Match
    '        If contentDisposition IsNot Nothing Then
    '            m = FilenameRegex.Match(contentDisposition)
    '            If m.Success Then
    '                attachmentsFound = True

    '                b.Append("<li>").Append(m.Groups("filename").Value).Append("</li>")
    '            End If
    '        ElseIf contentType IsNot Nothing Then
    '            m = NameRegex.Match(contentType)

    '            If m.Success Then
    '                attachmentsFound = True
    '                b.Append("<li>").Append(m.Groups("filename").Value).Append("</li>")
    '            End If
    '        End If
    '    Next
    '    b.Append("</ol>")
    '    If attachmentsFound Then
    '        AttachmentsLiteral.Text = b.ToString()
    '    Else
    '        AttachementsRow.Visible = False
    '    End If
    'End Sub

    Protected Function GetDecoder(charset As String) As Decoder
        Dim decoder As Decoder
        Select Case charset.ToLower()
            Case "utf-7"
                decoder = Encoding.UTF7.GetDecoder()
                Exit Select
            Case "utf-8"
                decoder = Encoding.UTF8.GetDecoder()
                Exit Select
            Case "us-ascii"
                decoder = Encoding.ASCII.GetDecoder()
                Exit Select
            Case "iso-8859-1"
                decoder = Encoding.ASCII.GetDecoder()
                Exit Select
            Case Else
                decoder = Encoding.ASCII.GetDecoder()
                Exit Select
        End Select
        Return decoder
    End Function

    Protected Function FormatUrls(plainText As String) As String
        Dim replacementLink As String = "<a href=""${url}"">${url}</a>"
        Return UrlRegex.Replace(plainText, replacementLink)
    End Function


End Class
